package cn.com.twoke.app.pin_dou_dou.utils;

import cn.com.twoke.app.pin_dou_dou.color.CIE_2000_Cached;
import cn.com.twoke.app.pin_dou_dou.color.ColorDifferenceCalculator;

import java.awt.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 颜色操作工具类
 */
public class ColorUtils {

    private static final ColorDifferenceCalculator calculator = new CIE_2000_Cached();
    // 缓存最接近颜色的查找结果，以提高性能
    private static final Map<Integer, Color> closestColorCache = new ConcurrentHashMap<>();

    /**
     * 在颜色集合中查找与目标颜色最相似的颜色
     * 使用缓存来避免重复计算
     * @param target 目标颜色
     * @param palette 颜色集合
     * @return 颜色集合中最接近的颜色
     */
    public static Color findClosestColor(Color target, Collection<Color> palette) {
        // 检查输入参数是否为空
        if (target == null || palette == null) {
            throw new IllegalArgumentException("目标颜色或颜色集合不能为空");
        }
        
        // 尝试从缓存中获取结果
        Integer targetRgb = target.getRGB();
        Color cachedResult = closestColorCache.get(targetRgb);
        if (cachedResult != null) {
            return cachedResult;
        }

        // 如果缓存中没有，则进行计算
        // 确保palette不为空
        if (palette.isEmpty()) {
            return target; // 如果调色板为空，则返回原色
        }
        
        Color result = palette.stream()
                .filter(Objects::nonNull) // 过滤掉空颜色
                .min(Comparator.comparingDouble(color ->
                        calculator.deltaE(target, color)))
                .orElse(target);

        // 将结果存入缓存
        closestColorCache.put(targetRgb, result);

        return result;
    }

    /**
     * 判断颜色是否为亮色
     * @param color 要判断的颜色
     * @return 如果是亮色返回true，否则返回false
     */
    public static boolean isLightColor(Color color) {
        // 将RGB值归一化到0-1范围
        double r = color.getRed() / 255.0;
        double g = color.getGreen() / 255.0;
        double b = color.getBlue() / 255.0;

        // 计算相对亮度（W3C标准）
        double luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;

        // 阈值设为0.5，大于0.5认为是亮色
        return luminance > 0.5;
    }

    /**
     * 根据背景色获取合适的文本颜色
     * @param backgroundColor 背景颜色
     * @return 黑色或白色，取决于哪种颜色在背景上更易读
     */
    public static Color getContrastColor(Color backgroundColor) {
        return isLightColor(backgroundColor) ? Color.BLACK : Color.WHITE;
    }

}